/**
 * Title: Hyperbolic engine
 * Description: jFamilyTree Engine
 * Version: provider
 * Copyright: (c) 2001-2008
 * Terms of use:see license agreement at http://treebolic.sourceforge.net/en/license.htm
 * Author: Bernard Bou
 * Company: bsys
 * Update: Mon Mar 10 00:00:00 CEST 2008
 */
package jFamilyTree.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;

import javax.swing.Timer;

import jFamilyTree.core.HyperTransform;

/**
 * Animator implements animation of tree
 * 
 * @author Bernard Bou
 */
public class Animator extends Timer
{
	private static final long serialVersionUID = 1L;

	class Job implements ActionListener
	{
		/**
		 * Animation iterator
		 */
		private Iterator<HyperTransform> theAnimationIterator;

		public Job(Animation thisAnimation)
		{
			theAnimationIterator = thisAnimation.theTransforms.iterator();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		public void actionPerformed(ActionEvent thisE)
		{
			if (theAnimationIterator == null || !theAnimationIterator.hasNext())
			{
				theAnimationIterator = null;
				stop();
				removeActionListener(this);
			}
			else
			{
				HyperTransform thisTransform = theAnimationIterator.next();
				theView.applyTransform(thisTransform);
				theView.repaint();
			}
		}
	}

	/**
	 * View
	 */
	private View theView;

	/**
	 * Start delay
	 */
	private int theStartDelay;

	/**
	 * Constructor
	 * 
	 * @param thisView
	 *        view
	 * @param thisTimerLapse
	 *        timer lapse
	 * @param thisStartDelay
	 *        start delay
	 */
	public Animator(View thisView, int thisTimerLapse, int thisStartDelay)
	{
		super(thisTimerLapse, null);
		theView = thisView;
		theStartDelay = thisStartDelay;
		setRepeats(true);
		setCoalesce(true);
	}

	/**
	 * Run animation
	 * 
	 * @param thisAnimation
	 *        animation
	 * @param now
	 *        whether to start now
	 * @return true if successful
	 */
	public boolean run(Animation thisAnimation, boolean now)
	{
		if (thisAnimation.theTransforms == null)
			return false;

		this.addActionListener(new Job(thisAnimation));

		setInitialDelay(now ? 0 : theStartDelay);
		start();
		return true;
	}
}
